package com.dries.chat.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.net.InetSocketAddress;

/**
 * @Description:
 * @Author ZSY
 * @createTime 2020/7/8 10:04
 */
@Data
@Slf4j
@Component
public class WSServer {

    /**
     * 监听端口
     */
    @Value("${netty.port}")
    private Integer port;
    // 创建两个线程组, bossGroup处理连接，workerGroup处理数据
    private final EventLoopGroup bossGroup = new NioEventLoopGroup(1);;
    private final EventLoopGroup workerGroup = new NioEventLoopGroup(); // 默认8个NioEventLoopGroup
    private final ServerBootstrap bootstrap = new ServerBootstrap();

    @PostConstruct
    public void start() throws InterruptedException {

        bootstrap.group(bossGroup, workerGroup)
                // 指定Channel
                .channel(NioServerSocketChannel.class)
                //使用指定的端口设置套接字地址
                .localAddress(new InetSocketAddress(port))
                // 服务端可连接队列数
                .option(ChannelOption.SO_BACKLOG, 1024)
                // 设置TCP长连接（长时间无数据通信，TCP会自动发送一个活动探测数据报文）
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                //将小的数据包包装成更大的帧进行传送，提高网络的负载,即TCP延迟传输
                .childOption(ChannelOption.TCP_NODELAY, true)
                .childHandler(new WSServerInitialzer());

        try {
            ChannelFuture future = bootstrap.bind(port).sync();
            // 监听关闭的channel，设置为同步方式
            // future.channel().closeFuture().sync();
            if (future.isSuccess()) {
                log.info("【netty 服务器启动 端口号： {}】", port);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @PreDestroy
    public void destroy() throws InterruptedException {
        bossGroup.shutdownGracefully().sync();
        workerGroup.shutdownGracefully().sync();
        log.info("【netty 服务器关闭】");
    }


}
